package ru.surfstudio.webservicetemplate.service;

import java.io.Serializable;

import org.springframework.util.Assert;

import ru.surfstudio.webservicetemplate.WSApplication;
import ru.surfstudio.webservicetemplate.exception.AuthenticationException;
import ru.surfstudio.webservicetemplate.exception.BusinessException;
import ru.surfstudio.webservicetemplate.exception.TransportException;
import ru.surfstudio.webservicetemplate.task.GetHttpTask;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.util.Log;

public class HttpService extends IntentService {

    private static final String TAG = "HttpService";

    public static final String EXTRA_STATUS_RECEIVER = "EXTRA_STATUS_RECEIVER";

    public static final String EXTRA_HTTP_TASK = "EXTRA_HTTP_TASK";

    public static final String EXTRA_RESULT = "EXTRA_RESULT";

    public static final String EXTRA_ERROR_CODE = "EXTRA_ERROR_CODE";

    public static final int STATUS_RUNNING = 0x1;

    public static final int STATUS_ERROR = 0x2;

    public static final int STATUS_FINISHED = 0x3;

    public static final int ERROR_CODE_BUSINESS = 0x1;

    public static final int ERROR_CODE_TRANSPORT = 0x2;

    protected RestExecutor remoteExecutor;

    public HttpService() {
        super(TAG);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        WSApplication app = (WSApplication)getApplication();
        remoteExecutor = new RestExecutor(app.getClientHttpRequestFactory());
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d(TAG, "onHandleIntent(intent=" + intent.toString() + ")");
        final ResultReceiver receiver = intent.getParcelableExtra((EXTRA_STATUS_RECEIVER));
        if (receiver != null) receiver.send(STATUS_RUNNING, Bundle.EMPTY);
        final Bundle resultBundle = new Bundle();
        int status;
        try {
            final long startRemote = System.currentTimeMillis();
            Serializable result = performAction(intent);
            Log.d(TAG, "remote request took " + (System.currentTimeMillis() - startRemote) + " ms");
            resultBundle.putSerializable(EXTRA_RESULT, result);
            status = STATUS_FINISHED;
        } catch (BusinessException e) {
            Log.e(TAG, "AuthenticationException while request", e);
            resultBundle.putInt(EXTRA_ERROR_CODE, ERROR_CODE_BUSINESS);
            status = STATUS_ERROR;
        } catch (Exception e) {
            Log.e(TAG, "Problem while request", e);
            resultBundle.putString(Intent.EXTRA_TEXT, e.toString());
            resultBundle.putInt(EXTRA_ERROR_CODE, ERROR_CODE_TRANSPORT);
            status = STATUS_ERROR;
        }
        if (receiver != null) receiver.send(status, resultBundle);
    }
    
    protected Serializable performAction(Intent intent) throws AuthenticationException, TransportException {
    	final GetHttpTask task = (GetHttpTask)intent.getSerializableExtra((EXTRA_HTTP_TASK));
    	Assert.notNull(task, "task must not be null");
    	return remoteExecutor.getForObject(task);
    }
}
